﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using umbraco.cms.presentation.Trees;
using System.Web;
using umbraco.cms.businesslogic;
using umbraco.BusinessLogic;

namespace DigibizTree.Picker
{
    public static class DigibizTreeExtensions
    {
        /// <summary>
        /// Determines if it needs to render a null tree based on the start node id and returns true if it is the case. 
        /// </summary>
        /// <param name="tree"></param>
        /// <param name="startNodeId"></param>
        /// <param name="rootNode"></param>
        /// <param name="app"></param>
        /// <returns></returns>
        internal static bool SetNullTreeRootNode(this BaseTree tree, int startNodeId, ref XmlTreeNode rootNode, string app)
        {
            if (startNodeId == DigibizConstants.NOACCESSID)
            {
                rootNode = new NullTree(app).RootNode;
                rootNode.Text = "You do not have permission for this media tree";
                rootNode.NodeID = startNodeId.ToString(); ;
                rootNode.HasChildren = false;
                rootNode.Source = string.Empty;
                rootNode.Action = string.Format("javascript:openMedia({0});", startNodeId);
                return true;
            }

            return false;
        }

        /// <summary>
        /// Used to determine the start node id while taking into account a user's security.
        /// </summary>
        /// <param name="tree"></param>
        /// <param name="definedStartNode"></param>
        /// <param name="userStartNode"></param>
        /// <returns></returns>
        internal static int GetStartNodeId(this BaseTree tree, Content definedStartNode, Content userStartNode)
        {
            if (userStartNode == null)
            {
                throw new ArgumentNullException("userStartNode");
            }

            //The output start node id.
            var determinedStartNodeId = -1;

            if (definedStartNode.Id == -1)
            {
                //If the id is -1, then the start node is the user's start node.
                determinedStartNodeId = userStartNode.Id;
            }
            else if (definedStartNode.Path.Split(',').Contains(userStartNode.Id.ToString()))
            {
                //If User's start node id is found in the defined path, then the start node id
                //can (allowed) be the defined path.
                //This should always work for administrator (-1).
                determinedStartNodeId = definedStartNode.Id;
            }
            else if (userStartNode.Path.Split(',').Contains(definedStartNode.Id.ToString()))
            {
                //If the defined start node id is found in the user's path, then the start node id
                //can only be the user's, not the actual start.
                determinedStartNodeId = userStartNode.Id;
            }
            else if (!definedStartNode.Path.Split(',').Contains(userStartNode.Id.ToString()))
            {
                //No access.
                determinedStartNodeId = DigibizConstants.NOACCESSID;
            }

            return determinedStartNodeId;
        }

        /// <summary>
        /// Returns the data type id for the current base tree.
        /// </summary>
        /// <remarks>
        /// The data type definition id is persisted between request as a query string.
        /// This is used to retreive values from the cookie which are easier persisted values
        /// than trying to append everything to custom query strings.
        /// </remarks>
        /// <param name="tree"></param>
        /// <returns></returns>
        internal static int GetDataTypeId(this BaseTree tree)
        {
            int id = -1;
            int.TryParse(tree.NodeKey, out id);
            return id;
        }

        /// <summary>
        /// Returns the start node id from the cookie for the current data type.
        /// </summary>
        /// <param name="tree"></param>
        /// <param name="dataTypeDefId"></param>
        /// <returns></returns>
        internal static int GetStartNodeIdFromCookie(this BaseTree tree, int dataTypeDefId)
        {
            //Try to read an existing cookie.
            var cookie = HttpContext.Current.Request.Cookies["DigibizPicker"];
            if (cookie != null && cookie.Values.Count > 0)
            {
                return cookie.GetStartNodeIdForDataType(dataTypeDefId);
            }
            return -1;
        }
        
        /// <summary>
        /// This will return the normal service url based on id but will also ensure that the data type definition id is passed through as the nodeKey param.
        /// </summary>
        /// <remarks>
        /// We only need to set the custom source to pass in our extra NodeKey data.
        /// By default the system will use one or the other: Id or NodeKey, in this case
        /// we are sort of 'tricking' the system and we require both.
        /// Umbraco allows you to theoretically pass in any source as long as it meets the standard
        /// which means you can pass around any arbitrary data to your trees in the form of a query string,
        /// though it's just a bit convoluted to do so.
        /// </remarks>
        /// <param name="id"></param>
        /// <param name="dataTypeDefId"></param>
        /// <returns></returns>
        internal static string GetTreeServiceUrlWithParams(this BaseTree tree, int id, int dataTypeDefId)
        {
            var url = tree.GetTreeServiceUrl(id);

            //Append the node key.
            return url + "&nodeKey=" + dataTypeDefId.ToString();
        }

    }
}
